import {_decorator, AnimationClip, Component, Node, SkeletalAnimation, SkeletalAnimationState, Vec3} from 'cc';
import {AudioManager} from "db://assets/scripts/common/AudioManager";
import {GameManager} from "db://assets/scripts/game/GameManager";
import {AudioPaths} from "db://assets/scripts/common/AudioPaths";
import {PlayerAnimationType} from "db://assets/scripts/game/role/player/PlayerAnimationType";
import {PlayerManager} from "db://assets/scripts/game/role/player/PlayerManager";
import {GameState} from "db://assets/scripts/game/GameState";

const {ccclass, property} = _decorator;

/**
 * 玩家角色模型脚本
 */
@ccclass('PlayerModelController')
export class PlayerModelController extends Component {
    /**
     * 弓箭发射的节点
     */
    @property(Node)
    public socketLooseNode: Node;
    /**
     * 手节点
     */
    @property(Node)
    public socketHandNode: Node;
    /**
     * 攻击时候展示的弓箭
     */
    @property(Node)
    public arrowNode: Node;
    /**
     * 动画播放组件
     */
    @property(SkeletalAnimation)
    public playerAnimation: SkeletalAnimation;

    /**
     * 射箭时的角度
     */
    public looseEulerAngles: Vec3 = new Vec3();
    /**
     * 当前动画是否正在播放
     */
    public isAniPlaying: boolean = false;
    /**
     * 动画类型
     */
    private animationType: string = "";
    /**
     * 动画播放状态
     */
    private animationState: SkeletalAnimationState;
    /**
     * 脚步
     */
    private stepIndex: number = 0;

    start() {

    }

    update(deltaTime: number) {

    }

    /**
     * 是否正在跑
     */
    public isRunning() {
        return this.animationType === PlayerAnimationType.RUN && this.isAniPlaying === true;
    }

    /**
     * 是否待机
     */
    public isIdle() {
        return this.animationType === PlayerAnimationType.IDLE && this.isAniPlaying === true;
    }

    /**
     * 是否正在攻击
     */
    public isAttacking() {
        return this.animationType === PlayerAnimationType.ATTACK && this.isAniPlaying === true;
    }

    /**
     * 初始化
     */
    public init() {
        this.hideArrow();
    }

    /**
     * attack帧事件:箭射出去的时候触发
     */
    public onFrameAttackLoose() {
        if (GameManager.getInstance().gameStateProxy.getGameState() === GameState.OVER || GameManager.getInstance().gameStateProxy.getGameState() === GameState.PAUSE) {
            return;
        }

        this.looseEulerAngles = this.node.parent?.eulerAngles as Vec3;
        GameManager.getInstance().gamePlayerProxy.getPlayerController()?.throwArrowToEnemy();
        PlayerManager.getInstance()?.throwArrowToEnemy();
        this.arrowNode.active = false;
        // console.log("looseEulerAngles", this.looseEulerAngles);
    }

    /**
     * run帧事件：脚落地的时候播放音效
     *
     * @see PlayerModelController
     */
    public onFrameRun() {
        this.stepIndex = this.stepIndex === 0 ? 1 : 0;
        AudioManager.getInstance().playSound(this.stepIndex === 0 ? AudioPaths.footStep1Sound : AudioPaths.footStep2Sound);
    }

    /**
     * attack帧事件: 拉弓的时候触发
     */
    public onFrameAttackDraw() {
        this.arrowNode.active = true;
    }

    /**
     * 隐藏模型手中默认的箭
     */
    public hideArrow() {
        this.arrowNode.active = false;
    }

    /**
     * 播放玩家动画
     *
     * @param {string} aniType 动画类型
     * @param {boolean} [isLoop=false] 是否循环
     * @param {Function} [callback] 回调函数
     * @param {number} [callback] 调用播放动画的位置，方便用于测试
     * @returns
     * @memberof Player
     */
    public playAni(aniType: string, isLoop: boolean = false, callback?: Function, pos?: number) {
        // console.log("playerAniType", aniType, "curAniType", this.aniType, "pos", pos);
        this.animationState = this.playerAnimation?.getState(aniType) as SkeletalAnimationState;

        if (this.animationState && this.animationState.isPlaying) {
            return;
        }

        this.animationType = aniType;

        if (this.animationType !== PlayerAnimationType.ATTACK) {
            this.hideArrow();
        }

        this.playerAnimation?.play(aniType);

        this.isAniPlaying = true;

        if (this.animationState) {
            if (isLoop) {
                this.animationState.wrapMode = AnimationClip.WrapMode.Loop;
            } else {
                this.animationState.wrapMode = AnimationClip.WrapMode.Normal;
            }

            switch (aniType) {
                case PlayerAnimationType.ATTACK:
                    // this.animationState.speed = GameManager.gameSpeed * GameManager.scriptPlayer.curAttackSpeed;
                    // GameManager.scriptPlayer.hideRunSmoke();
                    break;
                case PlayerAnimationType.RUN:
                    // console.log("run>>>>>>");
                    // this.animationState.speed = GameManager.gameSpeed * (GameManager.scriptPlayer.curMoveSpeed / GameManager.scriptPlayer.playerBaseInfo.moveSpeed);
                    // GameManager.scriptPlayer.playRunSmoke();
                    PlayerManager.getInstance()?.playRunSmoke();
                    break;
                case PlayerAnimationType.IDLE:
                    this.animationState.speed = GameManager.getInstance().gameSpeedProxy.getGameSpeed();
                    break;
                default:
                    this.animationState.speed = GameManager.getInstance().gameSpeedProxy.getGameSpeed();
                    break;
            }
        }

        if (!isLoop) {
            this.playerAnimation.once(SkeletalAnimation.EventType.FINISHED, () => {
                this.isAniPlaying = false;
                callback && callback();
            })
        }
    }
}